<?php

namespace App\Services;

use RuntimeException;
use Illuminate\Contracts\Encryption\DecryptException;
use App\Contracts\Decrypter as DecrypterContract;

class RSADecrypter implements DecrypterContract
{
    /**
     * 服务器私钥
     *
     * @var resource
     */
    protected $privateKey;

    /**
     * 返回一个新RSA加密器实例
     *
     * @param  string  $key
     * @param  string  $cipher
     * @return void
     *
     * @throws \RuntimeException
     */
    public function __construct($privateKeyPath)
    {
        // 读取私钥内容
        $privateKeyContent = file_get_contents($privateKeyPath);
        $privateKeyResource = openssl_pkey_get_private($privateKeyContent);
        if ($privateKeyResource === false) {
            throw new RuntimeException('RSA Key error.');
        }

        $this->privateKey = $privateKeyResource;
    }

    /**
     * Decrypt the given value.
     *
     * @param  mixed  $payload
     * @param  bool  $unserialize
     * @return mixed
     *
     * @throws \Illuminate\Contracts\Encryption\DecryptException
     */
    public function decrypt($payload)
    {
        $encrypted = base64_decode($payload);
        // 私钥解密
        $flag = openssl_private_decrypt($encrypted, $decrypted, $this->privateKey);
        // 异常处理
        if ($flag === false) {
            throw new DecryptException('Could not decrypt the data.');
        }
        // 返回结果
        return $decrypted;
    }
}
